...loading
2025-03-07

안녕하세요, 이번에는 블로그의 SEO 적용기를 작성해보려 합니다. 얼마전에 NextJS에서 SEO를 처리하는 방법에 대한 포스팅을 썼습니다.
해당 포스팅에서 Next의 metadata를 통해 SEO를 처리하는 방법에 대해 알아보았는데요, 이번에는 본 블로그의 코드에 직접 적용해보겠습니다. 사실 이전에 미리 구현한 Metadata 컴포넌트가 있었지만, 이번 포스팅에서 더 업그레이드 해보려합니다.
기존 코드에서도 metadata를 사용하여 SEO를 처리하고 있었습니다. 정적/동적 페이지에서 모두 사용할 수 있는 공용 컴포넌트를 만들어 적용했습니다. 그런데 얼마 전에 NextJs의 SEO처리에 대한 포스팅을 쓴 후 상당히 대충 구현한 컴포넌트였음이 반성됩니다.
import { Metadata } from "next"; import metadataString from "@/lib/metadata-string"; type MetadataProps = { page: string; isArticle?: boolean; articleSummary?: string; }; export function MetadataComponent({ page, isArticle, articleSummary, }: MetadataProps): Metadata { return { title: page === "Main" ? `Taki-Town` : `${page} | Taki-Town`, description: isArticle ? articleSummary : metadataString(page), robots: { index: true, follow: true, }, };
공용 컴포넌트의 내용입니다. props에 따라서 상응하는 결과를 내주는데, 너무 대충입니다. SEO를 처리하는 부분은 메인페이지와 포스팅페이지 뿐입니다. 가능하다면 모든 페이지에 따라 적절한 SEO처리를 해주는게 중요한데요, 따라서 더 구체적이고 세분화한 로직으로 바꿔보려 합니다. 그리고 자세히 보니, 해당 로직은 굳이 컴포넌트로 정의할 필요가 없습니다. 따라서 utils의 함수에서 처리해주도록 바꿉니다.
기존 코드에서는 하나의 로직에서 주요 페이지의 metadata를 한 번에 처리하려 하고 있습니다. 하지만 페이지 유형에 따라 조금씩 설정이 달라져야하는 metadata를 하나의 로직에서 다 처리해버린다면, 의존성이 높아집니다. 따라서 페이지 유형에 따라서 로직을 분리합니다. 분리 기준은 아래 세 가지와 같습니다.
: 페이지에서 동적으로 데이터를 받아와 metadata를 생성
: 홈페이지, 포스트 리스팅 페이지, 방명록 등에 적용합니다. 정적인 정보로 metadata를 생성합니다.
: 관리자 페이지로 SEO를 비활성화하는 설정을 포함한 metadata를 생성합니다.
위의 세 가지 유형의 페이지를 담당할 수 있는 metadata 생성기를 구현했습니다. 세 유형의 로직 모두 비슷하고, 약간의 데이터 설정만 다릅니다. 그렇기에 가장 중요한 포스팅/프로젝트 상세 페이지의 metadata 생성 코드만 확인해보겠습니다.
type ArticleCategory = "post" | "project"; type ArticleMetadataProps = { articleTitle: string; articleCategory: ArticleCategory; articleSummary: string; articleImageUrl: string; }; export function generateArticleMetadata({ articleTitle, articleCategory, articleSummary, articleImageUrl, }: ArticleMetadataProps): Metadata { return { title: `${articleTitle} | Taki-Town`, description: articleSummary, alternates: { canonical: `${process.env.PUBLIC_URL}/${articleCategory}/${articleTitle}`, }, openGraph: { title: articleTitle, description: articleSummary, url: `${process.env.PUBLIC_URL}/${articleCategory}/${articleTitle}`, images: [ { url: articleImageUrl, width: 1200, height: 630, alt: `아티클 '${articleTitle}'의 대표이미지`, }, ], }, robots: { index: true, follow: true, }, }; }
설정하는 metadata에 특별한 부분은 없습니다. 기본적인 내용과 openGraph를 통해 SNS에서의 링크 공유 시 최적화된 방식으로 전달되도록 설정합니다. 그리고 robots 속성을 통해 SEO와 크롤링에 대한 활성화도 열어줍니다. 다음에는 페이지 컴포넌트에서 구체적으로 어떻게 적용했는지 살펴보겠습니다.
// 포스팅 상세 페이지에서의 적용 // import etc.. import { generateArticleMetadata } from "@/utils/metadata"; export async function generateMetadata({ // 동적 메타데이터 생성 params, }: { params: { postSlug: string }; }) { const data = await fetchPostData(params.postSlug); return generateArticleMetadata({ // 동적으로 생성한 메타데이터 리턴 articleTitle: data.title, articleCategory: "post", articleSummary: data.summary, articleImageUrl: data.imageLink, }); } export default async function PostSlug({ params, }: { params: { postSlug: string }; }) { //... }
해당 포스팅 페이지는 동적으로 라우팅된 페이지입니다. 따라서 메타데이타 또한 동적으로 불러와야하기에, nextJs의 generateMetadata를 사용하여 DB로부터 동적인 데이터 정보를 불러옵니다. 그리고 만들어둔 metadata 생성기를 적용하여, 해당 포스팅 내용에 최적화된 metadata를 반환받게 됩니다.
이상으로 metadata를 통한 SEO 적용기를 마치겠습니다. 추후 도메인을 사, 정식적인 사이트로 배포되었을 때 구글에서 잘 노출되면 좋겠습니다 ..ㅎ 그리고 코드를 리팩토링 하다보니, 부족한 부분들이 많이 보입니다. 조금 더 생각하면서 코드를 작성하는 습관을 들여야겠습니다. 다음에도 다른 작업일지로 돌아오겠습니다.
Comments